home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-05
/
scnsrv.zip
/
NEWNOV.C
< prev
next >
Wrap
Text File
|
1992-10-23
|
17KB
|
743 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <conio.h>
#include <dir.h>
#include <share.h>
#include <errno.h>
#include <sys\stat.h>
#include <dos.h>
#include "version.h"
#pragma hdrstop
#include "newnov.h"
unsigned int
IntSwap(unsigned int t)
{
asm {
mov ax,t
xchg ah,al
mov t,ax
}
return t;
}
unsigned long
LongSwap(unsigned long t)
{
asm {
mov ax,word ptr t
xchg ah,al
mov bx,word ptr t+2
mov word ptr t+2,ax
mov ax,bx
xchg ah,al
mov word ptr t,ax
}
return t;
}
// --------------------------------------------------------------------------
// int GetDirectoryHandle(driveNumber)
//
// Calls the Netware API to get info regarding a drive (A..Z)(1..26) and the
// temporary drives 27 to 32. Returns flags in high byte of int, Directory
// Handle in the low byte.
//
// CAUTION: Netware numbers drives from ZERO, we number from ONE, and make
// the adjustment to zero-based within these Netware routines.
// --------------------------------------------------------------------------
int
GetDirectoryHandle(driveNumber)
{
int res;
_DX = (unsigned) driveNumber-1;
_AX = 0xE900;
geninterrupt(0x21);
res = _AX;
return res;
}
int
GetPreferredConnectionID(void)
{
_AX = 0xF001;
geninterrupt(0x21);
return _AL;
}
void
SetPreferredConnectionID(int connectionID)
{
_AX = 0xF000;
_DL = connectionID;
geninterrupt(0x21);
}
struct ConnectionIDTable far *
GetConnIDTable(void)
{
unsigned segp, offp;
_AX = 0xEF03;
asm push es
asm push si
geninterrupt(0x21);
asm mov segp,es
asm mov offp,si
asm pop si
asm pop es
return MK_FP(segp,offp);
}
struct DriveConnectionIDTable far *
GetDriveConnIDTable(void)
{
unsigned segp, offp;
_AX = 0xEF02;
asm push es
asm push si
geninterrupt(0x21);
asm mov segp,es
asm mov offp,si
asm pop si
asm pop es
return MK_FP(segp,offp);
}
struct FileServerNameTable far *
GetFSNameTable(void)
{
unsigned segp, offp;
_AX = 0xEF04;
asm push es
asm push si
geninterrupt(0x21);
asm mov segp,es
asm mov offp,si
asm pop si
asm pop es
return MK_FP(segp,offp);
}
int
GetConnectionID(char *serverName, int *connectionIDP)
{
int i;
struct ConnectionIDTable far *idtp = GetConnIDTable();
struct FileServerNameTable far *nmtp = GetFSNameTable();
// loop thru the file server name table/connection ID table, looking for
// a fileservername
strupr(serverName);
for (i=1; i<=8; i++, idtp++) {
if (
(idtp->slotInUse) &&
(idtp->connectionNumber != 0xFF) &&
(idtp->connectionStatus == 0xFF) &&
(!strcmp(serverName, nmtp->ServerName[i-1]))
)
{
*connectionIDP = i;
return 0;
}
}
return NERR_NOCONN;
}
int
GetNextServer(char *serverName, int *connectionIDP)
{
int i = *connectionIDP + 1;
struct ConnectionIDTable far *idtp = GetConnIDTable() + i - 1;
struct FileServerNameTable far *nmtp = GetFSNameTable();
// loop thru the file server name table/connection ID table, looking for
// a valid table entry. Start with the previous connection index. (Use
// 0 to begin a new search.
for (; i<=8; i++, idtp++) {
if (
(idtp->slotInUse) &&
(idtp->connectionNumber != 0xFF) &&
(idtp->connectionStatus == 0xFF)
)
{
strcpy(serverName, nmtp->ServerName[i-1]);
*connectionIDP = i;
return 0;
}
}
return NERR_NOCONN;
}
// --------------------------------------------------------------------------
// int FindMappedDrive(char *serverName, char *volumeName, int *driveP, char *path)
//
// Calls the Netware APIs to find the first network-mapped drive that is
// currently connected to a given server and volume. Useful for conserving
// drive letters. Only permanent drives are examined.
//
// If the optional path parameter is non-null, then a drive won't be accepted
// in the search, unless the given path is accessible from that drive. This
// is to prevent problems with fake root mappings on Netware 386 systems.
//
// Return drive number (1..26) if OK, or -1 if couldn't find such a drive,
// or if an error occurs during the search.
// --------------------------------------------------------------------------
int
FindMappedDrive(char *serverName, char *volumeName, char *path)
{
int i, connID;
int savedisk = getdisk();
struct DriveConnectionIDTable far *dcidtp;
char pathName[255];
strupr(serverName); strupr(volumeName);
// First, determine the connection ID of the server we need.
if (GetConnectionID(serverName, &connID))
return -1;
// Get a pointer to the drive connection ID table.
dcidtp = GetDriveConnIDTable();
if (!dcidtp)
return -1;
// Now, look at each drive that is mapped to that server (i.e., the
// connection ID in the Drive Connection ID table matches).
for (i=1; i<=26; i++) {
if (dcidtp->connID[i-1] == connID) {
// Found a possible match. Check the volume it's mapped to...
// (We get the dir path for the handle associated with the drive,
// then see if the beginning of the path matches the volumeName).
if (!GetDirectoryPath(GDH_HANDLE(GetDirectoryHandle(i)), pathName)) {
if
(
// the volume name mapped to matches what we want...
!strncmp(pathName, volumeName, strlen(volumeName)) &&
(pathName[strlen(volumeName)] == ':') &&
// and if the optional path access is achievable...
(
path &&
(setdisk(i-1), !access(path, 0))
)
)
{
setdisk(savedisk);
return i;
}
}
else
continue;
}
}
setdisk(savedisk);
return -1;
}
// --------------------------------------------------------------------------
// int AllocateDirHandle(char *volumeName,
// int drive, int handle, int opcode);
//
// Calls the Netware API to allocate a dir handle to a SERVER\VOLUME:
// combination, or to deallocate a previously-allocated handle.
//
// --------------------------------------------------------------------------
int
AllocateDirHandle(char *volumeName, int drive, int handle, int opcode)
{
struct AllocateDirHandleRequest req;
struct NovellReply reply = { 2, 0, 0 };
unsigned segq, offq, segp, offp, res;
memset(req.path, 0, sizeof(req.path));
strcat(req.path, volumeName);
strcat(req.path, ":");
strupr(req.path);
req.pathLength = strlen(req.path);
req.length = sizeof(req) - 2;
req.reqFcnCode = opcode;
req.dirHandle = handle;
req.driveLetter = drive + 'A' - 1;
if (opcode == ADH_DEALLOC)
reply.length = 0;
segq = FP_SEG((void far *) &req);
offq = FP_OFF((void far *) &req);
segp = FP_SEG((void far *) &reply);
offp = FP_OFF((void far *) &reply);
asm push di
asm push si
asm push es
asm push ds
asm mov ax,0xe200
asm mov si,offq
asm mov di,offp
asm mov es,segp
asm mov ds,segq
asm int 0x21
asm pop ds
asm pop es
asm pop si
asm pop di
asm mov ah,0
asm mov res,ax
return res;
}
// --------------------------------------------------------------------------
// int GetDirectoryPath(int dirHandle, char *pathOutBuf);
//
// Calls the Netware API to find a dir handle's path. Puts the path
// into pathOutBuf, which must be at least 255 bytes.
//
// --------------------------------------------------------------------------
int
GetDirectoryPath(int dirHandle, char *pathOutBuf)
{
struct GetDirectoryPathRequest req;
struct GetDirectoryPathReply reply;
unsigned segq, offq, segp, offp, res;
reply.length = sizeof(reply) - 2;
req.length = sizeof(req) - 2;
req.reqFcnCode = 1; // Get Dir Handle's Path...
req.dirHandle = dirHandle;
segq = FP_SEG((void far *) &req);
offq = FP_OFF((void far *) &req);
segp = FP_SEG((void far *) &reply);
offp = FP_OFF((void far *) &reply);
asm push di
asm push si
asm push es
asm push ds
asm mov ax,0xe200
asm mov si,offq
asm mov di,offp
asm mov es,segp
asm mov ds,segq
asm int 0x21
asm pop ds
asm pop es
asm pop si
asm pop di
asm mov ah,0
asm mov res,ax
// if successful, move the path into the callers buffer
if (!res)
{
memcpy(pathOutBuf, reply.path, reply.dirPathLen);
pathOutBuf[reply.dirPathLen] = '\0';
}
else
sprintf(pathOutBuf, "badHandle, err = 0x%2.2x", res);
return res;
}
int
GetVolumeName(char *volName, int volIndex)
{
struct GetVolumeNameRequest req;
struct GetVolumeNameReply reply;
unsigned segq, offq, segp, offp, res;
reply.length = sizeof(reply) - 2;
req.length = sizeof(req) - 2;
req.function = 6;
req.volNumber = volIndex;
segq = FP_SEG((void far *) &req);
offq = FP_OFF((void far *) &req);
segp = FP_SEG((void far *) &reply);
offp = FP_OFF((void far *) &reply);
asm push di
asm push si
asm push es
asm push ds
asm mov ax,0xe200
asm mov si,offq
asm mov di,offp
asm mov es,segp
asm mov ds,segq
asm int 0x21
asm pop ds
asm pop es
asm pop si
asm pop di
asm mov ah,0
asm mov res,ax
// if successful, move the path into the callers buffer
if (!reply.volnameLength)
res = -1;
if (!res)
{
memcpy(volName, reply.volName, reply.volnameLength);
volName[reply.volnameLength] = '\0';
}
return res;
}
// --------------------------------------------------------------------------
// void DumpDriveMapping(void)
// --------------------------------------------------------------------------
void
DumpDriveMapping(void)
{
int dirHandle, handleType, driveNum, driveConn,
saveConn = GetPreferredConnectionID();
char path[255];
struct DriveConnectionIDTable far *dcidtp = GetDriveConnIDTable();
struct FileServerNameTable far *fsnmtp = GetFSNameTable();
cprintf("------------ Dump Drive Mapping ----------------------\r\n");
for (driveNum = 1; driveNum <= 32; driveNum++) {
dirHandle = GetDirectoryHandle(driveNum);
handleType = GDH_MASK(dirHandle);
dirHandle = GDH_HANDLE(dirHandle);
driveConn = dcidtp->connID[driveNum-1];
switch (handleType) {
case GDH_LOCAL:
break;
case GDH_UNMAPPED:
break;
case GDH_MAP_PERM:
handleType = 'P';
goto printit;
case GDH_MAP_TEMP:
handleType = 'T';
printit:
SetPreferredConnectionID(driveConn);
GetDirectoryPath(dirHandle, path);
cprintf("Drive %c: (#%d/%c) %s\\%s\r\n", driveNum+'A'-1, driveNum, handleType,
fsnmtp->ServerName[driveConn-1], path);
break;
default:
break;
}
}
SetPreferredConnectionID(saveConn);
getch();
}
// --------------------------------------------------------------------------
// int NovMapDrive(int *drive, char *server, char *volume)
//
// Maps an unmapped drive number to a server and volume. Returns one of the
// NERR codes upon error, or 0 if OK. Returns NERR_NODRIVE if all drives
// are already mapped.
//
// int NovUnMapDrive(int drive);
//
// Unmaps a drive mapped by NovMapDrive(). Returns 0 if OK, or NERR_xxxx if
// error.
// --------------------------------------------------------------------------
int
NovMapDrive(int *drive, char *server, char *volume)
{
int res;
int savePrefConnID, newConnID;
// Find the server...
if ((res = GetConnectionID(server, &newConnID)) != 0)
return NERR_NOCONN;
// change to that one for preferred connection
savePrefConnID = GetPreferredConnectionID();
SetPreferredConnectionID(newConnID);
for (*drive = 1; *drive < 26; (*drive)++)
{
if (GDH_MASK(GetDirectoryHandle(*drive)) == GDH_UNMAPPED)
break;
}
if (*drive >= 26) {
SetPreferredConnectionID(savePrefConnID);
return NERR_NODRIVE;
}
res = AllocateDirHandle(volume, *drive, 0, ADH_PERM);
SetPreferredConnectionID(savePrefConnID);
return res;
}
int
NovUnMapDrive(int drive, char *server)
{
int res;
int dirhandle;
int savePrefConnID, newConnID;
// Find the server...
if ((res = GetConnectionID(server, &newConnID)) != 0)
return NERR_NOCONN;
// change to that one for preferred connection
savePrefConnID = GetPreferredConnectionID();
SetPreferredConnectionID(newConnID);
dirhandle = GDH_HANDLE(GetDirectoryHandle(drive));
res = AllocateDirHandle("", drive, dirhandle, ADH_DEALLOC);
SetPreferredConnectionID(savePrefConnID);
return res;
}
int
GetFileInfo(char *path, struct NovellFileInfo *nfip, int in_seqnum)
{
struct GetFileInfoRequest req;
struct GetFileInfoReply reply;
unsigned segq, segp, offq, offp;
int res = 0;
// init the request struct with the path...
strcpy(req.path, path);
req.pathLen = strlen(path);
req.length = sizeof(req) - 2;
req.function = 0x0F;
req.seqnum = in_seqnum;
req.dirHandle = 0;
req.searchAttribs = 0x6; // djdjdjdj hack, s/b a parameter....
// initialize the reply packet...
reply.length = sizeof(reply) - 2;
// make the call!
segq = FP_SEG((void far *) &req);
offq = FP_OFF((void far *) &req);
segp = FP_SEG((void far *) &reply);
offp = FP_OFF((void far *) &reply);
asm push di
asm push si
asm push es
asm push ds
asm mov ax,0xe300
asm mov si,offq
asm mov di,offp
asm mov es,segp
asm mov ds,segq
asm int 0x21
asm pop ds
asm pop es
asm pop si
asm pop di
asm mov ah,0
asm mov res,ax
// If successful, copy the results to the file info struct....
if (!res)
{
memcpy(nfip->filename, reply.filename, sizeof(nfip->filename));
nfip->fileAttributes = reply.fileAttributes;
nfip->extendedFileAttributes = reply.extendedFileAttributes;
// nfip->reserved = reply.reserved;
nfip->creationDate = reply.creationDate;
nfip->accessDate = reply.accessDate;
nfip->updateTime = reply.updateTime;
nfip->ownerID = reply.ownerID;
nfip->archiveTime = reply.archiveTime;
nfip->seqnum = reply.seqnum;
nfip->fileSize = reply.fileSize;
memcpy(nfip->reserved_buf, &(reply.reserved_buf),
sizeof(nfip->reserved_buf));
}
return res;
}
int
SetFileInfo(char *path, struct NovellFileInfo *nfip)
{
struct SetFileInfoRequest req;
int reply = 0;
unsigned segq, segp, offq, offp;
int res = 0;
// init the request struct with file info...
strcpy(req.path, path);
req.pathLen = strlen(path);
req.fileAttributes = nfip->fileAttributes;
req.extendedFileAttributes = nfip->extendedFileAttributes;
req.reserved = 0; // nfip->reserved;
req.creationDate = nfip->creationDate;
req.accessDate = nfip->accessDate;
req.updateTime = nfip->updateTime;
req.ownerID = nfip->ownerID;
//req.ownerID = 0;
req.archiveTime = nfip->archiveTime;
// memcpy(&(req.reserved_buf), nfip->reserved_buf,
// sizeof(req.reserved_buf));
memset(&(req.reserved_buf), 0, sizeof(req.reserved_buf));
req.length = sizeof(req) - sizeof(req.path) + req.pathLen - 2;
req.function = 0x10;
req.dirHandle = 0;
req.searchAttribs = 6; // djdjdjdj hack, s/b a parameter....
// make the call!
segq = FP_SEG((void far *) &req);
offq = FP_OFF((void far *) &req);
segp = FP_SEG((void far *) &reply);
offp = FP_OFF((void far *) &reply);
asm push di
asm push si
asm push es
asm push ds
asm mov ax,0xe300
asm mov si,offq
asm mov di,offp
asm mov es,segp
asm mov ds,segq
asm int 0x21
asm pop ds
asm pop es
asm pop si
asm pop di
asm mov ah,0
asm mov res,ax
return res;
}
// If this call returns success, then it might actually be out of directories.
// This can be detected because the subdirNumber won't change.
int
GetDirInfo(char *path, struct ScanDirInfoReply *dip)
{
struct ScanDirInfoRequest req;
unsigned segq, segp, offq, offp;
int res = 0;
// init the request struct with the path...
strcpy(req.path, path);
req.pathLen = strlen(path);
// req.length = sizeof(req) - 2;
req.length = sizeof(req) - sizeof(req.path) + req.pathLen - 2;
req.function = 0x02;
req.subdirNumber = IntSwap(dip->subdirNumber+1);
req.dirHandle = 0;
// initialize the reply packet...
dip->length = sizeof(*dip) - 2;
// make the call!
segq = FP_SEG((void far *) &req);
offq = FP_OFF((void far *) &req);
segp = FP_SEG((void far *) dip);
offp = FP_OFF((void far *) dip);
asm push di
asm push si
asm push es
asm push ds
asm mov ax,0xe200
asm mov si,offq
asm mov di,offp
asm mov es,segp
asm mov ds,segq
asm int 0x21
asm pop ds
asm pop es
asm pop si
asm pop di
asm mov ah,0
asm mov res,ax
dip->subdirNumber = IntSwap(dip->subdirNumber);
return res;
}